package com.jplus.mvc.web;

import java.io.IOException;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jplus.core.anno.boot.Component;
import com.jplus.core.mvc.HandlerInterceptorAdapter;
import com.jplus.core.mvc.WebUtil;
import com.jplus.core.mvc.vo.Model;
import com.jplus.core.mvc.vo.ModelAndView;
import com.jplus.core.utill.JSON;
import com.jplus.core.utill.JUtil;

/**
 * 请求拦截器
 * 
 * @author Yuanqy
 *
 */
@Component
public class WebInterceptor extends HandlerInterceptorAdapter {
	private final Logger log = LoggerFactory.getLogger(WebInterceptor.class);
	private final ThreadLocal<Long> consumTime = new ThreadLocal<>();

	@PostConstruct
	public void init() {
		log.info("[init]>> HttpIntercepter ...");
	}

	/**
	 * 在preHandle中，可以进行编码、安全控制等处理； 实现预处理
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		consumTime.set(System.currentTimeMillis());
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		log.info("[>> New {} Request URI:{}]", request.getMethod(), request.getRequestURI());
		Map<String, Object> params = getParams();
		if (!params.isEmpty())
			log.info("[>> Params]:{}", params);
		return true;
	}

	private void doAuth(HttpServletResponse response) throws IOException {
		response.setContentType("text/html; charset=ISO-8859-1");
		response.setStatus(401);
		response.addHeader("WWW-Authenticate", "Basic realm=\"\"");
		response.getWriter().println(JSON.toJSONString(new Model().FAIL().DATA("请先登录")));
	}

	/**
	 * 在postHandle中，有机会修改ModelAndView； 后处理（调用了Service并返回ModelAndView，但未进行页面渲染）
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		log.debug("[>> 请求成功处理]");
		if (modelAndView != null)
			modelAndView.addObject("v", consumTime.get());
	}

	/**
	 * 在afterCompletion中，可以根据ex是否为null判断是否发生了异常，进行日志记录。 返回处理（已经渲染了页面）
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		log.info("[>> End {} Request URI:{}]\tTime:{}ms Code:{}\n ", request.getMethod(), request.getRequestURI(),
				(System.currentTimeMillis() - consumTime.get()), response.getStatus());
		consumTime.remove();
		if (ex != null) {
			Throwable t = ex.getCause();
			if (t instanceof IllegalArgumentException) {// 1类异常处理
				WebUtil.writeJSON(new Model().FAIL().DATA(t.getMessage()));
			} else {
				WebUtil.writeJSON(new Model().FAIL().DATA("系统异常，请稍后再试~"));
				log.error("ERROR:", ex);
			}
		}
	}

	/**
	 * Responsebody 返回前
	 */
	@Override
	public void beforeBodyWrite(HttpServletResponse response, Object body) {
		if (body != null)
			log.info("[>> Response]:" + JSON.toJSONString(body));
	}

	private Map<String, Object> getParams() {
		Map<String, Object> maps = WebUtil.getRequestParamMap();
		Object img = maps.get("image");
		if (img != null)
			maps.put("image", new String[] { "[base64-image]" });// 特殊参数
		return maps;
	}

}
